<template>
  <div class="page-message-box">
    <div class="chat-box">
      <!-- 消息盒子头部 -->
      <div class="chat-box-top">
        {{ $t('chat.messageBox') }}
      </div>

      <div class="chat-box-main">
        <!-- 消息盒子左侧栏 -->
        <div class="chat-box-left">
          <!-- 左侧用户信息栏 -->
          <ul
            v-if="friends.length"
            v-infinite-scroll="onScrollUserList"
            class="shop-list"
            infinite-scroll-immediate="false"
          >
            <li
              v-for="(item, index) in friends"
              :key="index"
              :class="['shop-item',item.userId === selectedF ? 'changeUser' : '',item.message?'newMessage':'']"
              :style="{
                backgroundColor: item.userId === selectedF ? '#D0E9FF' : '',
              }"
              @click="changeImContent(item.userId)"
            >
              <div class="shop-icon">
                <img
                  v-if="!item.pic"
                  src="../../../assets/img/userImg.jpg"
                  alt="item.pic"
                >
                <img
                  v-else
                  :src="checkFileUrl(item.pic)"
                  alt=""
                >
              </div>
              <div class="shop-info">
                <span class="shop-info-name">
                  <span class="name">{{ item.friendName }}</span>
                  <span
                    v-if="item.unread > 0"
                    class="tips"
                  >{{ item.unread }}</span>
                </span>
                <span class="shop-info-icon">{{ item.latestMsg }}</span>
              </div>
            </li>
          </ul>
          <div
            v-else
            class="empty-contacts"
          >
            <img
              src="@/assets/img/empty/empty_contacts.png"
              :alt="$t('chat.noContacts')"
              class="empty-img"
            >
            <span class="empty-txt">{{ $t('chat.noContacts') }}</span>
          </div>
        </div>

        <!-- 消息盒子右侧信息回复栏 -->
        <div class="chat-box-right">
          <div class="im-box">
            <div class="im-main">
              <div class="chat-main-form">
                <div class="display-infor">
                  <div
                    v-if="moreMess && pages>1"
                    class="more"
                    @click="moreInfo()"
                  >
                    {{ $t('chat.clickToLoadMore') }}
                  </div>
                  <div
                    v-if="!moreMess && pages>1"
                    class="more"
                  >
                    {{ $t('chat.noMore') }}
                  </div>
                  <div
                    v-for="(row, index) in msgList"
                    :key="index"
                    class="msg-list-box"
                  >
                    <!-- 用户消息 -->
                    <div class="topTime">
                      {{ row.timeStr }}
                    </div>
                    <!-- 用户发出的消息 -->
                    <div
                      v-if="+row.source === 2"
                      class="my"
                    >
                      <!-- 左-头像 -->
                      <div class="left">
                        <img
                          v-if="!row.userHeadUrl"
                          src="../../../assets/img/userImg.jpg"
                          class="avatar"
                          alt="头像"
                        >
                        <img
                          v-else
                          :src="checkFileUrl(row.userHeadUrl)"
                          class="avatar"
                          alt="头像"
                        >
                      </div>
                      <!-- 右-消息 -->
                      <div class="right">
                        <div class="username">
                          <div class="name">
                            {{ row.userName }}
                          </div>
                        </div>
                        <div
                          v-if="+row.type === 1 && !row.prodInfo"
                          class="bubble"
                        >
                          <el-image
                            :src="checkFileUrl(row.content)"
                            class="longimage"
                            :preview-src-list="[row.content]"
                          />
                        </div>
                        <!-- 文字消息 -->
                        <div
                          v-if="+row.type === 0 && !row.prodInfo"
                          class="bubble"
                        >
                          <span>{{ row.content }}</span>
                        </div>
                        <!-- 商品链接 -->
                        <div
                          v-if="row.prodInfo"
                          class="prod-link"
                        >
                          <div class="link-prod">
                            <div
                              v-if="row.prodInfo.orderFlag"
                              class="prod-number"
                              @click="toProdDetail(row.prodInfo,1,row.prodInfo.orderType)"
                            >
                              {{ $t('chat.orderNumber') }}:{{ row.prodInfo.orderNumber }}
                            </div>
                            <div
                              class="prod-box"
                              @click="toProdDetail(row.prodInfo,0,row.prodInfo.orderType)"
                            >
                              <img
                                :src="checkFileUrl(row.prodInfo.imgs)"
                                alt=""
                              >
                              <div class="link-detail">
                                <div class="prod-name">
                                  {{ row.prodInfo.prodName }}
                                </div>
                                <div class="prod-price">
                                  <span>{{ row.prodInfo.price?'￥':'' }}{{ row.prodInfo.price?row.prodInfo.price:'' }}{{ (row.prodInfo.price && row.prodInfo.useScore)?'+':'' }}<span v-if="row.prodInfo.useScore">{{ row.prodInfo.useScore }} {{ $t('order.integral') }}</span></span>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <!-- 别人发出的消息 -->
                    <div
                      v-if="
                        (+row.source === 0 || +row.source === 1) && (+row.forwardCode !== 1)
                      "
                      class="other"
                    >
                      <!-- 右-商家名称-时间-消息 -->
                      <div class="left">
                        <div class="username">
                          <div class="name">
                            {{ row.nickName||row.shopName }}
                          </div>
                        </div>
                        <div class="message-box">
                          <div
                            v-if="row.userUnread"
                            class="unread"
                          >
                            {{ $t('chat.read') }}
                          </div>
                          <div
                            v-if="!row.userUnread"
                            class="unread"
                          >
                            {{ $t('chat.unRead') }}
                          </div>
                          <!-- 文字消息 -->
                          <div
                            v-if="+row.type === 0"
                            class="bubble"
                          >
                            <span>{{ row.content }}</span>
                          </div>
                          <!-- 图片消息 -->
                          <div
                            v-if="+row.type === 1"
                            class="bubble"
                          >
                            <el-image
                              :src="checkFileUrl(row.content)"
                              class="longimage"
                              :preview-src-list="[row.content]"
                            />
                          </div>
                        </div>
                        <div
                          v-if="row.employeeId !== employeeIdShop "
                          class="take-charge-of"
                        >
                          {{ $t('chat.transferred') }}
                        </div>
                      </div>
                      <!-- 头像 -->
                      <div class="right">
                        <img
                          :src="checkFileUrl(row.shopLogo)"
                          class="avatar"
                          alt="图片"
                        >
                      </div>
                    </div>
                    <div
                      v-if="lastMsgEmployeeId!== null && lastMsgEmployeeId !== employeeIdShop && index === msgList.length -1"
                      class="transInfo"
                    >
                      <div
                        class="topTrans"
                      >
                        {{ $t('chat.transferInfo') + lastMsgEmployeeName + $t('chat.transferInfoLast') }}
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 下方发送信息栏 -->
                <div class="reply">
                  <div class="small-box">
                    <div class="upload" />
                    <div
                      class="customerService"
                      @click="onCustomerService()"
                    >
                      {{ $t('chat.transferToCustomerService') }}
                      <el-tooltip
                        effect="dark"
                        :content="$t('chat.transferTips')"
                        placement="right"
                      >
                        <el-icon><QuestionFilled /></el-icon>
                      </el-tooltip>
                    </div>
                  </div>
                  <label
                    for="iii"
                    class="imgUp"
                  ><a
                    class="upload"
                  /></label>
                  <input
                    id="iii"
                    ref="fileRef"
                    accept="image/png, image/jpeg"
                    type="file"
                    class="input-upload-btn"
                    @change="onToolEvent"
                  >
                  <div class="reply-area">
                    <textarea
                      id=""
                      v-model="textMsg"
                      name=""
                      cols="20"
                      rows="4"
                      @keydown="onMessageSendlisten($event)"
                    />
                  </div>
                  <div
                    class="send"
                    @click="onSendText()"
                  >
                    {{ $t('chat.send') }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 转接客服弹窗 -->
    <el-dialog
      v-model="visible"
      :title="$t('chat.selectOnlineCustomerService')"
      :modal="false"
      top="60px"
      width="1200px"
      :close-on-click-modal="false"
      append-to-body
    >
      <div class="service-select-body">
        <el-table
          ref="prodTableRef"
          :data="serviceList"
          border
          style="width: 100%"
        >
          <el-table-column
            width="50"
            header-align="center"
            align="center"
          >
            <template #default="scope">
              <div>
                <el-radio
                  v-model="employeeId"
                  :label="scope.row.employeeId"
                  @change="onGetSelectProdRow(scope.row)"
                >
&nbsp;
                </el-radio>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="employeeNickname"
            header-align="center"
            align="center"
            :label="$t('homes.userName')"
          />
        </el-table>
      </div>
      <template #footer>
        <span>
          <el-button @click="visible = false">{{
            $t("crud.filter.cancelBtn")
          }}</el-button>
          <el-button
            type="primary"
            @click="onConfirmService()"
          >{{
            $t("crud.filter.submitBtn")
          }}</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { uploadFile } from '@/utils/http.js'
import { ElMessage, ElMessageBox } from 'element-plus'
import { clearLoginInfo, checkFileUrl } from '@/utils/index.js'
import { Base64 } from 'js-base64'
import $t from '@/utils/$t.js'
import cookie from 'vue-cookies'
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()

let ws = null
let userId = '' // 用户id
let shopId = '' // 店铺id
let userRead = true // 用户的已读未读判断
let userSend = false // 是否是用户发送的消息判断
let ortherUser = false // 别的账号登录判断
let currentUserId = '' // 当前用户id
let lockReconnect = false // 判断有无客服连接上
let switchingHistory = null // 判断是否是转接客服的历史记录
let messageReminding = null // 消息提醒时器
let messageInfo = {} // 商家发送的文本消息
let plooTime = 0 // 重连次数
let shopInfo = {} // 店铺信息
let noAccountable = true
let current = 1 // 聊天内容当前页
let userCurrent = 1 // 左侧用户栏当前页
let userPages = 1
const defaultTitle = document.title // 存储默认标题
let nickName = '' // 当前管理员昵称
let newUserIndex = null // 订单用户下标

const visible = ref(false) // 客服转接弹窗显隐
const friends = ref([])
const msgList = ref([])
const pages = ref(1)
const selectedF = ref(null) // 选中的用户
const serviceList = ref([])
const textMsg = ref('') // 文本信息
const employeeId = ref(0) // 选中的客服id
const employeeName = ref('') // 选中的客服的名称
const employeeIdShop = ref(0) // 负责人id
const moreMess = ref(false) // true 有更多 false 没有更多

const lastMsgEmployeeId = ref(null) // 最后发消息的客服id
const lastMsgEmployeeName = ref('') // 最后发消息的客服名称
onMounted(() => {
  onGetUserInfo()
  onGetShopInfo()
  localStorage.setItem('b2cImBoxShop', true)
})

onBeforeUnmount(() => {
  if (ws != null) {
    ws.close()
  }
})

// 清除消息提醒时器
const onClearMeagess = () => {
  clearInterval(messageReminding)
  document.title = defaultTitle
}
// 消息提醒标题闪烁
const messageRemindingFn = () => {
  window.onfocus = function () {
    onClearMeagess()
  }
  onClearMeagess()
  messageReminding = setInterval(() => {
    const title = document.title
    // 如果没有获取焦点就判断名称是否包含未读消息
    if (/您有新消息/.test(title) === false) {
      // 如果包含就显示为空
      document.title = '【您有新消息】'
    } else {
      // 否则显示未读消息，间隔0.5秒实现闪烁
      document.title = defaultTitle
    }
  }, 500)
}
const onGetShopInfo = () => {
  http({
    url: http.adornUrl('/shop/shopDetail/info'),
    method: 'GET'
  }).then(({ data }) => {
    shopInfo = data
    employeeIdShop.value = data.employeeId
  })
}
// 获取当前管理员信息
const onGetUserInfo = () => {
  http({
    url: http.adornUrl('/sys/user/info'),
    method: 'get',
    params: http.adornParams()
  }).then(({ data }) => {
    shopId = data.shopId
    userId = data.userId
    nickName = data.nickname
    onGetConversations()
  })
}
/**
 * 获取左侧历史联系人信息
 */
const onGetConversations = async () => {
  window.onfocus = function () {
    onClearMeagess()
  }
  window.onblur = function () {
    messageReminding = null
  }
  // 防止已在在消息盒子页面右下方弹出不停弹出
  window.onbeforeunload = function () {
    if (route.name === 'message-box') {
      localStorage.removeItem('b2cImBoxShop')
    }
  }
  const { data } = await http({
    url: http.adornImUrl('/p/shop/conversations') + '?current=' + userCurrent + '&size=20',
    method: 'POST'
  })
  if (data.records && data.pages) {
    data.records.forEach(item => {
      const isJsonRes = onCheckJSON(item.latestMsg)
      if (item.type === 1) {
        item.latestMsg = '[' + $t('publics.image') + ']'
      } else if (isJsonRes && JSON.parse(item.latestMsg) instanceof Object) {
        item.latestMsg = '[' + $t('chat.productLinks') + ']'
      }
    })
    // sort按时间正序排序 最新的消息在前面
    data.records.sort(function (a, b) {
      return b.timestamp - a.timestamp
    })
    if (userCurrent > 1) {
      friends.value.forEach(item => {
        data.records = data.records.filter(itemInde => {
          return item.userId !== itemInde.userId
        })
      }) // 过滤左侧已存在的用户
      friends.value = friends.value.concat(data.records)
    } else {
      if (route.query.userId) {
        const tempUserId = route.query.userId
        // 用户要是已存在就记录下标
        const newUserFlag = data.records.some((item, index) => {
          if (item.userId === tempUserId) {
            newUserIndex = index
          }
          return item.userId === tempUserId
        }) // 过滤已存在的用户

        if (newUserFlag) {
          friends.value = data.records
          friends.value = elChangeExForArray(newUserIndex, 0, friends.value)
          currentUserId = tempUserId
        } else {
          const res = await http({
            url: http.adornImUrl('/p/shop/userInfo?userId=' + tempUserId),
            method: 'GET'
          })
          friends.value.push(res.data[0])
          currentUserId = res.data[0].userId
          friends.value = friends.value.concat(data.records)
        }
      } else {
        friends.value = data.records
        currentUserId = data.records[0].userId
      }
      openWs() // 开启webstocket
    }
    userPages = data.pages
  } else {
    // 商家联系买家
    if (route.query.orderNumber && route.query.userId && !friends.value.length) {
      getNewUser()
    } else {
      openWs() // 开启webstocket
    }
  }
}
// 添加新的用户栏到左侧
const getNewUser = async () => {
  const res = await http({
    url: http.adornImUrl('/p/shop/userInfo?userId=' + route.query.userId),
    method: 'GET'
  })
  friends.value.push(res.data[0])
  currentUserId = res.data[0].userId
  selectedF.value = res.data[0].userId
  openWs() // 开启webstocket
}
// 交换两个数组的位置
const elChangeExForArray = (index1, index2, array) => {
  const temp = array[index1]
  array[index1] = array[index2]
  array[index2] = temp
  return array
}

// 心跳检测, 每隔一段时间检测连接状态，如果处于连接中，就向server端主动发送消息，来重置server端与客户端的最大连接时间，如果已经断开了，发起重连。
const onHeartCheck = {
  timeout: 19000, // 19s发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。 尽量一个小时发送三次
  serverTimeoutObj: null,
  reset: function () {
    clearTimeout(this.serverTimeoutObj)
    return this
  },
  start: function () {
    this.serverTimeoutObj = setTimeout(function () {
      if (!ws) {
        return
      }
      if (ws.readyState === 1) {
        // 连接状态，发送消息保持连接
        ws.send(
          JSON.stringify({
            sendType: undefined,
            content: 'HEART_BEAT',
            msgType: 0,
            toId: currentUserId
          })
        )
        onHeartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
      } else {
        ws.close()
        ws = null
        // 断开状态，尝试重连
        lockReconnect = false
      }
    }, this.timeout)
  }
}
/**
 * 开启webstocket
 */
const openWs = () => {
  ws = new WebSocket(
    http.adornWsImUrl(
      '/im/websocket/shop/' +
      Base64.encode(cookie.get('b2cAuthorization')) + '/' + shopId + '/' + userId
    )
  )
  ws.onopen = function () {
    onHeartCheck.reset().start() // 成功建立连接后，重置心跳检测
    ortherUser = false
    getMsgItems()
  }
  ws.onmessage = (res) => {
    onHeartCheck.reset().start() // 成功建立连接后，重置心跳检测
    const result = JSON.parse(res.data)
    onHandleWsMsg(result)
  }
}

const onHandleWsMsg = (result) => {
  if (result.code !== '00000') {
    result.code = Number(result.code)
  }
  if (result.code === 10) {
    clearLoginInfo()
    router.push({
      name: 'login'
    })
    return
  }
  if (result.code === 11) {
    ortherUser = true
    ElMessageBox.confirm($t('idIsLoginInElse'), {
      showClose: false,
      showCancelButton: false,
      confirmButtonText: $t('homes.yes')
    }).then(() => {
      window.close()
    })
    return
  }
  if (result.code === 12) {
    return
  }
  if (result.code === 15) {
    ElMessage.error($t('chat.notYourResponsibility'))
    noAccountable = false
    return false
  }
  if (!result.data) {
    return
  }

  // 新的聊天信息
  if (result.code === '00000' || result.code === 4) {
    onHandleNewChat(result)
  }

  // 聊天记录
  if (result.code === 2) {
    onHandleChatLog(result)
  }

  // 转接客服
  if (result.code === 3) {
    serviceList.value = result.data
  }

  // 未读信息转成已读
  if (result.code === 5) {
    if (userSend) {
      userRead = false
      userSend = false
      pushMsgItem(messageInfo)
    }
    msgList.value.forEach(item => {
      item.userUnread = 1
    })
  }
  ws.onclose = () => {
    if (!ortherUser) {
      ortherUser = false
      if (plooTime < 3) {
        plooTime++
        if (lockReconnect) return
        lockReconnect = true
        // 没连接上会一直重连，设置延迟避免请求过多
        setTimeout(() => {
          openWs()
          lockReconnect = false
        }, 2000)
      } else {
        ElMessageBox.confirm($t('chat.connetBroken'), $t('chat.tips'), {
          confirmButtonText: $t('chat.confirm'),
          cancelButtonText: $t('chat.cancel'),
          type: 'warning'
        }).then(() => {
          location.reload()
        }).catch(() => {})
      }
    }
  }
}

// 处理新的聊天信息
const onHandleNewChat = (result) => {
  let index = null
  // 消息提醒标题闪烁
  if (result.data && !messageReminding) {
    messageRemindingFn()
  }

  if (result.data) {
    // 进行未读消息的加减
    if (friends.value.length && result.code !== 4) {
      friends.value.forEach((item, indexx) => {
        if (item.userId === result.data.userId) {
          index = indexx
        }
      })
      if (index != null && selectedF.value !== result.data.userId) {
        friends.value[index].unread = Number(friends.value[index].unread) + 1
      }
    }
  }

  if (msgList.value.length) {
    // 时间转换
    const prevTime = tsToDate(msgList.value[msgList.value.length - 1].timestamp, 'M月D日 h:m')
    const nowTime = tsToDate(result.data.timestamp, 'M月D日 h:m')
    if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
      result.data.timeStr = tsToDate(new Date().getTime(), 'h:m')
    } else {
      result.data.timeStr = tsToDate(new Date().getTime(), 'M月D日 h:m')
    }
  }

  if (result.code === 4) {
    currentUserId = result.data.userId
    onClearMeagess()
    switchingHistory = 1
    if (!friends.value.length) {
      friends.value.unshift({
        pic: result.data.userHeadUrl,
        friendName: result.data.userName,
        latestMsg: result.data.content,
        shopId: result.data.shopId,
        unread: 0,
        userId: result.data.userId,
        message: result.data.userId === currentUserId ? 0 : 1,
        employeeId: result.employeeId,
        nickName: result.nickName
      })
    }
    getMsgItems(1)
  }

  if (result.data.userId === currentUserId) {
    const readed = {
      read: 1,
      msgIds: [result.data.itemId],
      toId: currentUserId,
      sendType: 0
    }
    ws.send(JSON.stringify(readed))
  }

  changeFriendsWhenMsg(result.data)
  if (result.data.userId === currentUserId) {
    pushMsgItem(result.data)
  }
}

// 聊天记录处理
const onHandleChatLog = (result) => {
  const msgIds = []
  let index = null
  if (result && result.data.pages) {
    result.data.records = result.data.records.reverse()
    if (friends.value.length) {
      friends.value.forEach((item, indexx) => {
        if (item.userId === result.data.records[0].userId) {
          index = indexx
          lastMsgEmployeeId.value = friends.value[indexx].employeeId
          lastMsgEmployeeName.value = friends.value[indexx].nickName
        }
      })
    }
    if (lastMsgEmployeeId.value && result.data.records[0].employeeId !== employeeIdShop.value) {
      lastMsgEmployeeId.value = null
      lastMsgEmployeeName.value = ''
    }
    // 进行是否是商品链接的判断
    result.data.records.forEach(item => {
      const isJsonRes = onCheckJSON(item.content)

      if (isJsonRes && JSON.parse(item.content) instanceof Object) {
        item.prodInfo = JSON.parse(item.content)
      }

      item.timeStr = tsToDate(item.timestamp, 'M月D日 h:m')

      if (item.type === 1 && !isJsonRes) {
        item.content = item.content.indexOf(import.meta.env.VITE_APP_RESOURCES_URL) === 0 ? item.content : import.meta.env.VITE_APP_RESOURCES_URL + item.content
      }
      if (!item.employeeUnread) {
        // 进行未读消息的加减
        if (friends.value[index].unread !== 0) {
          friends.value[index].unread = 0
        }
        msgIds.push(item.itemId)
      }
    })

    const readed = {
      read: 1,
      msgIds,
      toId: currentUserId,
      sendType: 0
    }
    ws.send(JSON.stringify(readed))

    result.data.records.reduce((prev, cur) => {
      // 将时间更换为某某月某某日 要是是当天即去掉月日
      const now = tsToDate(prev.timestamp, 'M月D日 h:m')
      const next = tsToDate(cur.timestamp, 'M月D日 h:m')
      if (now.slice(0, now.indexOf(' ')) === next.slice(0, next.indexOf(' '))) {
        cur.timeStr = tsToDate(cur.timestamp, 'h:m')
      }
      // 历史记录进行时间段显示判断
      if (result.data.records.length > 2) {
        const timeFlag = timeBeApart(prev.timestamp, cur.timestamp)
        if (timeFlag) {
          delete cur.timeStr
        }
      }
      return cur
    })
  }

  if (current === 1) {
    msgList.value = result.data.records || []
    pages.value = result.data.pages
    switchingHistory = null // 重置转接客服聊天消息
    onScrollToBottom()
  }

  if (current !== 1) {
    // 数组反转拼接
    result.data.records = result.data.records.reverse()

    if (!switchingHistory) {
      result.data.records.forEach(item => {
        msgList.value.unshift(item)
      })
    } else {
      result.data.records = result.data.records.reverse()
      msgList.value = result.data.records || []
      pages.value = result.data.pages
      switchingHistory = null // 重置转接客服聊天消息
      current = 1
    }
  }
  moreMess.value = result.data.pages > 1
  if (result.data.pages !== 0) {
    selectedF.value = result.data.records[0].userId
  } else {
    selectedF.value = route.query.userId ? route.query.userId : ''
  }
}

/**
 * 转接客服
 */
const onCustomerService = () => {
  const msgInfo = {
    toId: currentUserId,
    employeeList: true,
    msgType: 0
  }
  ws.send(JSON.stringify(msgInfo))
  const time = setTimeout(() => {
    if (noAccountable) visible.value = true
    clearTimeout(time)
  }, 100)
}
/**
 * 有消息过来的时候，改变左边历史联系人列表（先删除消息对应联系人的信息，再将联系人放到第一个）
 */
const changeFriendsWhenMsg = (msgItem) => {
  // 消息内容
  let msgContent
  const isJson = onCheckJSON(msgItem.content)
  // 图片消息
  if (msgItem.type === 1) {
    msgContent = '[' + $t('publics.image') + ']'
  } else if (isJson && JSON.parse(msgItem.content) instanceof Object) {
    msgContent = '[' + $t('chat.productLinks') + ']'
  } else {
    msgContent = msgItem.content
  }
  for (let i = 0; i < friends.value.length; i++) {
    const item = friends.value[i]
    // 更新最新消息
    if (msgItem.userId === item.userId) {
      item.latestMsg = msgContent
      item.timeStr = msgItem.timeStr
      msgItem.unread = item.unread
      friends.value.splice(i, 1)
      break
    }
  }

  // 新消息
  friends.value.unshift({
    pic: msgItem.userHeadUrl,
    friendName: msgItem.userName,
    latestMsg: msgContent,
    unread: msgItem.unread || (currentUserId === msgItem.userId ? msgItem.unread : 1),
    shopId: msgItem.shopId,
    userId: msgItem.userId,
    employeeId: msgItem.employeeId,
    nickName: msgItem.nickName
  })
}

const onCheckJSON = (str) => {
  if (typeof str === 'string') {
    try {
      JSON.parse(str)
      return true
    } catch (e) {
      return false
    }
  }
}
/**
 * 换个联系人聊条
 */
const changeImContent = (itemUserId) => {
  if (currentUserId === itemUserId) {
    return
  }
  currentUserId = itemUserId
  current = 1
  noAccountable = true
  getMsgItems()
}
/**
 * 获取聊天记录
 */
const getMsgItems = () => {
  const msgInfo = {
    history: true,
    current,
    size: 10,
    sendType: 0,
    toId: currentUserId
  }
  ws.send(JSON.stringify(msgInfo))
}

/**
 * 添加联系人发送过来的消息内容
 */
const pushMsgItem = msgItem => {
  if (!msgItem) return
  if (msgItem.type === 1) {
    msgItem.content = import.meta.env.VITE_APP_RESOURCES_URL + msgItem.content
  }

  const isJsonRes = onCheckJSON(msgItem.content)
  if (isJsonRes && JSON.parse(msgItem.content) instanceof Object) {
    msgItem.prodInfo = JSON.parse(msgItem.content)
  }
  // 首次进入
  if (msgList.value.length) {
    const prevTime = tsToDate(msgList.value[msgList.value.length - 1].timestamp, 'M月D日 h:m')
    const nowTime = tsToDate(msgItem.timestamp, 'M月D日 h:m')
    if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
      msgItem.timeStr = tsToDate(new Date().getTime(), 'h:m')
    } else {
      msgItem.timeStr = tsToDate(new Date().getTime(), 'M月D日 h:m')
    }
    const timeFlag = timeBeApart(msgList.value[msgList.value.length - 1].timestamp, new Date().getTime())
    if (timeFlag) {
      delete msgItem.timeStr
    }
  } else {
    msgItem.timeStr = tsToDate(new Date().getTime(), 'M月D日 h:m')
  }
  msgItem.timestamp = new Date().getTime()

  msgList.value.push(msgItem)
  noAccountable = true
  onScrollToBottom()
}

/**
 * textarea回车事件
 */
const onMessageSendlisten = (event) => {
  if (event.keyCode === 13) {
    onSendText() // 发送文本
    event.preventDefault() // 阻止浏览器默认换行操作
    return false
  }
}

/**
 * 发送文本消息
 */
const onSendText = () => {
  if (textMsg.value === '' || !currentUserId || textMsg.value.match(/^\s+$/)) {
    return
  }
  const msgInfo = {
    toId: currentUserId,
    content: textMsg.value,
    msgType: 0
  }
  onAddMessage(msgInfo)
  textMsg.value = ''
}
const onAddMessage = (msgInfo) => {
  userRead = true // 重置,防止用户不在线时可以继续发消息
  userSend = true
  ws.send(JSON.stringify(msgInfo))
  const msgItem = {
    shopName: shopInfo.shopName,
    shopLogo: shopInfo.shopLogo,
    userUnread: 0,
    employeeId: employeeIdShop.value,
    type: msgInfo.msgType,
    timestamp: new Date(),
    source: 1,
    content: msgInfo.content,
    nickName
  }
  messageInfo = msgItem
  const time = setTimeout(() => {
    if (noAccountable && userRead) {
      pushMsgItem(msgItem)
      userSend = false
    } else {
      messageInfo = null
    }
    clearTimeout(time)
  }, 200)
}

// 发送图片
const fileRef = ref(null)
const onToolEvent = () => {
  const selectFileobj = fileRef.value.files[0] || null
  http({
    url: http.adornUrl('/admin/file/getPreSignUrl'),
    method: 'get',
    params: http.adornParams({
      fileName: selectFileobj.name,
      isImFile: true
    })
  }).then(({ data }) => {
    uploadFile(data.preSignUrl, selectFileobj).then(() => {
      http({
        url: http.adornUrl('/admin/file/uploadSuccess'),
        method: 'put',
        data: [{
          fileId: data.fileId,
          attachFileGroupId: 0,
          fileSize: selectFileobj.size
        }]
      }).then(() => {
        const msgInfo = {
          toId: currentUserId,
          content: data.filePath,
          msgType: 1
        }
        fileRef.value.value = null // 解决上传同一图片不显示bug
        onAddMessage(msgInfo)
      })
    })
  })
}
/**
 * 改变日期
 */
const tsToDate = (number, format) => {
  const formateArr = ['Y', 'M', 'D', 'h', 'm', 's']
  const returnArr = []

  const date = new Date(number)
  returnArr.push(date.getFullYear())
  returnArr.push(
    date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
  )
  returnArr.push(
    date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  )

  returnArr.push(
    date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  )
  returnArr.push(
    date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  )
  returnArr.push(
    date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  )

  for (const i in returnArr) {
    format = format.replace(formateArr[i], returnArr[i])
  }
  return format
}

/**
 * 进行相隔时间判断
 *
 * true 删除显示时间
 * false 保留显示时间
 */
const timeBeApart = (uppTime, preTime) => {
  if (!uppTime) {
    return false
  }
  const dateDiff = preTime - uppTime// 时间差的毫秒数
  const dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000))// 计算出相差天数
  const leave1 = dateDiff % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数
  const hours = Math.floor(leave1 / (3600 * 1000))// 计算出小时数
  // 计算相差分钟数
  const leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数
  const minutes = Math.floor(leave2 / (60 * 1000))// 计算相差分钟数

  return !(dayDiff >= 1 || hours >= 1 || minutes > 4)
}

/**
 * 主体消息点击加载更多
 */
const moreInfo = () => {
  current += 1
  if (current > pages.value) {
    moreMess.value = false
  } else {
    switchingHistory = null
    getMsgItems()
  }
}

/**
 * 滚动加载用户列表
 */
const onScrollUserList = () => {
  userCurrent += 1
  if (userCurrent <= userPages) {
    onGetConversations()
  }
}

// 滚动条自动到底部
const onScrollToBottom = () => {
  nextTick(() => {
    const msg = document.getElementsByClassName('display-infor')[0] // 获取对象
    msg.scrollTop = msg.scrollHeight // 滚动高度
  })
}

// 选中客服
const onGetSelectProdRow = (row) => {
  employeeId.value = row.employeeId
  employeeName.value = row.employeeNickname
}
/**
 * 转接客服确定
 */
const onConfirmService = () => {
  if (employeeId.value) {
    const msgInfo = {
      toId: currentUserId,
      changeTo: 1,
      employeeId: employeeId.value,
      msgType: 0
    }
    ws.send(JSON.stringify(msgInfo))
    visible.value = false
  } else {
    ElMessage.error($t('chat.pleaseSelectAcustomerService'))
  }
  lastMsgEmployeeId.value = employeeId.value
  lastMsgEmployeeName.value = employeeName.value
  employeeId.value = 0
}

/**
 * 链接点击去往商品详情或订单详情
 */
const toProdDetail = (prodInfo, type, orderType) => {
  let routeUrl = null
  const menuList = JSON.parse(sessionStorage.getItem('b2cMenuList'))
  if (type !== 0 || prodInfo.orderFlag) {
    // 判断是否有访问路由的权限
    const flag = isAuth(menuList, orderType === 3 ? 'user/integrals-manage/order/index' : 'order/order-manage/order/index')
    if (!flag) {
      ElMessage({
        message: '您暂时没有权限访问',
        type: 'error',
        duration: 1500
      })
      return
    }
    routeUrl = router.resolve({
      path: orderType === 3 ? '/user/integrals-manage/order/index' : '/order/order-manage/order/index',
      query: {
        orderNumber: prodInfo.orderNumber
      }
    })
  } else {
    const flag = isAuth(menuList, orderType === 3 ? 'user/integrals-manage/score-prod-list/index' : 'prod/prod/index')
    if (!flag) {
      ElMessage({
        message: '您暂时没有权限访问',
        type: 'error',
        duration: 1500
      })
      return
    }
    let prodName = prodInfo.prodName
    const skuName = prodInfo.skuName
    const prodId = prodInfo.prodId

    if (skuName) {
      let prodNameArray = prodName.split(' ')
      const skuNameArray = skuName.split(' ')

      // 过滤掉sku名称
      prodNameArray = prodNameArray.filter(item => {
        return skuNameArray.every(item1 => {
          return item !== item1
        })
      })
      prodName = prodNameArray.join('')
    }
    routeUrl = router.resolve({
      path: orderType === 3 ? '/user/integrals-manage/score-prod-list/index' : '/prod/prod/index',
      query: {
        prodName,
        prodId
      }
    })
  }
  window.open(routeUrl.href, '_blank', 'noopener,noreferrer')
}
/* 判断是否拥有进入路由页面的权限 */
const isAuth = (routeList, path) => {
  let flag = false

  for (let i = 0; i < routeList.length; i++) {
    if (flag === true) {
      break
    }
    if (routeList[i].url === path) {
      flag = true
      break
    }
    if (routeList[i].list) {
      flag = isAuth(routeList[i].list, path)
    }
  }
  return flag
}
</script>

<style lang="scss" scoped>
@use './index.scss';
</style>
